﻿using System;
using System.Diagnostics.Contracts;
using System.Windows;
using System.Windows.Media;
using OpenLS.Core;
using OpenLS.Drawing;

namespace OpenLS.Spreadsheet
{
    internal struct CellDisplayInfoKey
    {
        public readonly double ActualCharacterWidth;
        private readonly object _rawFormattedValue;
        public double ActualFontSizeInPixel;
        public UnderlineType ActualFontUnderline;
        public SpreadsheetColor ActualForeground;
        public double ActualWidth;
        public ColorScheme ColorScheme;
        public Format Format;
        public bool IsVertical;
        public int Rotation;
        public TextAlignment TextAlignment;
        public TextWrapping TextWrapping;
        public Typeface Typeface;
        public object Value;
        private ColorMode mode;
        public Cell Cell;

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (obj.GetType() != typeof (CellDisplayInfoKey)) return false;
            return Equals((CellDisplayInfoKey) obj);
        }
        public CellDisplayInfoKey(Cell cell, ColorMode mode)
        {
            Contract.Requires(cell != null);
            this.mode = mode;
            ActualCharacterWidth = cell.Column.ActualCharacterWidth;
            TextWrapping = cell.TextWrapping;
            _rawFormattedValue = cell.GetRawFormattedValue();
            Format = cell.Format;
            Value = cell.Value;
            ActualWidth = cell.Column.ActualWidth;
            Rotation = cell.Rotation;
            IsVertical = cell.IsVertical;
            ActualFontUnderline = cell.ActualFontUnderline;
            TextAlignment = cell.TextAlignment;
            ActualFontSizeInPixel = cell.ActualFontSizeInPixel;
            Typeface = cell.Typeface;
            ColorScheme = cell.Worksheet.Workbook.ColorScheme;
            ActualForeground = cell.ActualForeground;
            this.Cell = cell;
        }

        public object GetRawFormattedValue()
        {
            return _rawFormattedValue;
        }

        public object GetRawFormattedValue(int i)
        {
            return Cell.GetRawFormattedValue(i);
        }


        public bool Equals(CellDisplayInfoKey other)
        {
            return other.ActualCharacterWidth.Equals(ActualCharacterWidth) && Equals(other._rawFormattedValue, _rawFormattedValue) && other.ActualFontSizeInPixel.Equals(ActualFontSizeInPixel) && Equals(other.ActualFontUnderline, ActualFontUnderline) && Equals(other.ActualForeground, ActualForeground) && other.ActualWidth.Equals(ActualWidth) && Equals(other.ColorScheme, ColorScheme) && Equals(other.Format, Format) && other.IsVertical.Equals(IsVertical) && other.Rotation == Rotation && Equals(other.TextAlignment, TextAlignment) && Equals(other.TextWrapping, TextWrapping) && Equals(other.Typeface, Typeface) && Equals(other.Value, Value) && Equals(other.mode, mode);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int result = ActualCharacterWidth.GetHashCode();
                result = (result*397) ^ (_rawFormattedValue != null ? _rawFormattedValue.GetHashCode() : 0);
                result = (result*397) ^ ActualFontSizeInPixel.GetHashCode();
                result = (result*397) ^ ActualFontUnderline.GetHashCode();
                result = (result*397) ^ (ActualForeground != null ? ActualForeground.GetHashCode() : 0);
                result = (result*397) ^ ActualWidth.GetHashCode();
                result = (result*397) ^ (ColorScheme != null ? ColorScheme.GetHashCode() : 0);
                result = (result*397) ^ (Format != null ? Format.GetHashCode() : 0);
                result = (result*397) ^ IsVertical.GetHashCode();
                result = (result*397) ^ Rotation;
                result = (result*397) ^ TextAlignment.GetHashCode();
                result = (result*397) ^ TextWrapping.GetHashCode();
                result = (result*397) ^ (Typeface != null ? Typeface.GetHashCode() : 0);
                result = (result*397) ^ (Value != null ? Value.GetHashCode() : 0);
                result = (result*397) ^ mode.GetHashCode();
                return result;
            }
        }
    }
}